package com.bw.house.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bw.area.client.TbDictionaryClient;
import com.bw.broker.client.BrokerFeignService;
import com.bw.house.service.*;
import com.bw.house.mapper.TbHouseInfoMapper;
import com.bw.po.*;
import com.bw.result.ResponseState;
import com.bw.result.ResultVo;
import com.bw.util.SnowflakeIdWorker;
import com.bw.vo.*;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import nonapi.io.github.classgraph.json.Id;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.jdbc.object.UpdatableSqlQuery;
import org.springframework.stereotype.Service;


import java.util.*;
import java.util.concurrent.TimeUnit;

/**
* @author 25728
* @description 针对表【tb_house_info(房源信息表)】的数据库操作Service实现
* @createDate 2023-11-11 08:34:02
*/
@Service
@Slf4j
public class TbHouseInfoServiceImpl extends ServiceImpl<TbHouseInfoMapper, TbHouseInfo>
    implements TbHouseInfoService{
    private SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0,0);

    @Autowired
    private BrokerFeignService brokerFeignService;
    @Autowired
    private TbResourceService tbResourceService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private TbAdminService tbAdminService;
    @Autowired
    private TbHouseInfoMapper tbHouseInfoMapper;
    @Autowired
    private TbDictionaryClient tbDictionaryClient;
    @Autowired
    private TbHouseExamineService tbHouseExamineService;
    @Autowired
    private TbHouseFeatureService tbHouseFeatureService;
    @Override
    public ResultVo add(TbHouseInfoVo tbHouseInfoVo, String token) {
        TbHouseInfo tbHouseInfo = new TbHouseInfo();
        //将vo对象转为po对象
        BeanUtils.copyProperties(tbHouseInfoVo,tbHouseInfo);
        tbHouseInfo.setId(String.valueOf(idWorker.nextId()));
        QueryWrapper<TbHouseInfo> tbHouseInfoQueryWrapper = new QueryWrapper<>();
        tbHouseInfoQueryWrapper.lambda().eq(TbHouseInfo::getName,tbHouseInfoVo.getName());
        //获取一个房源
        TbHouseInfo one = tbHouseInfoMapper.selectOne(tbHouseInfoQueryWrapper);
        if (null!=one){
            return ResultVo.FAILED(ResponseState.EXIST);
        }
        //添加室外图片
        String uuid = String.valueOf(idWorker.nextId());
        List<String> resource = tbHouseInfoVo.getResource();
        batchAddResource(resource,uuid);
        //添加房产证图片
        String uuidTwo = String.valueOf(idWorker.nextId());
        List<String> houseCerti = tbHouseInfoVo.getHouseCerti();
        batchAddResource(houseCerti,uuidTwo);
        //添加室内图片
        String uuidThree = String.valueOf(idWorker.nextId());
        List<String> indoor = tbHouseInfoVo.getIndoor();
        batchAddResource(indoor,uuidThree);
        //添加户型图片
        String uuidFour = String.valueOf(idWorker.nextId());
        List<String> houseType = tbHouseInfoVo.getHouseTypeImg();
        batchAddResource(houseType,uuidFour);
        //添加
        tbHouseInfo.setResourceId(uuid);
        tbHouseInfo.setHouseCertiId(uuidTwo);
        tbHouseInfo.setIndoorId(uuidThree);
        tbHouseInfo.setHouseTypeId(uuidFour);
        int save = tbHouseInfoMapper.insert(tbHouseInfo);
        boolean examineSave= false;
        if (save==1){
            //添加审核数据
            TbHouseExamine tbHouseExamine = new TbHouseExamine();
            tbHouseExamine.setHouseId(tbHouseInfo.getId());
            Claims claims = Jwts.parser().setSigningKey("SearchHouse"
            ).parseClaimsJws(token).getBody();
            Integer id = (Integer) claims.get("id");
            tbHouseExamine.setUserId(id.toString());
            //审核类型为发布
            tbHouseExamine.setTypeId(tbHouseInfoVo.getExamineTypeId());
            //后台添加审核状态为已通过
            tbHouseExamine.setStatus(1);
            tbHouseExamine.setId(String.valueOf(idWorker.nextId()));
            examineSave = tbHouseExamineService.save(tbHouseExamine);
            //添加房源特色
            TbHouseFeature tbHouseFeature = new TbHouseFeature();
            tbHouseFeature.setHouseId(tbHouseInfo.getId());
            tbHouseFeature.setId(String.valueOf(idWorker.nextId()));
            tbHouseFeature.setProprietorMentality(tbHouseInfoVo.getProprietorMentality());
            tbHouseFeature.setCoreSellPoint(tbHouseInfoVo.getCoreSellPoint());
            tbHouseFeature.setServerIntro(tbHouseInfoVo.getServerIntro());
            tbHouseFeatureService.save(tbHouseFeature);
        }
        return save==1&&examineSave?ResultVo.SUCCESS():ResultVo.FAILED(ResponseState.INSERT_ERROR);
    }

    private void batchAddResource(List<String> resource, String resourceId) {
        TbResource tbResource = new TbResource();
        for (String imgUrl : resource) {
            tbResource.setId(String.valueOf(idWorker.nextId()));
            tbResource.setResourceId(resourceId);
            tbResource.setUrl(imgUrl);
            tbResourceService.save(tbResource);
        }
        tbResource = null;
    }

    @Override
    public ResultVo update(TbHouseInfoVo tbHouseInfoVo) {
        TbHouseInfo tbHouseInfo = new TbHouseInfo();
        //将vo对象转为po对象
        BeanUtils.copyProperties(tbHouseInfoVo,tbHouseInfo);
        QueryWrapper<TbHouseInfo> tbHouseInfoQueryWrapper = new QueryWrapper<>();
        tbHouseInfoQueryWrapper.lambda().eq(TbHouseInfo::getId,tbHouseInfo.getId());
        //获取一个房源
        TbHouseInfo one = tbHouseInfoMapper.selectOne(tbHouseInfoQueryWrapper);
        if (null == one){
            return ResultVo.FAILED(ResponseState.NOT_EXIST);
        }
        //清除图片
        batchDeletedResource(one.getResourceId());
        batchDeletedResource(one.getHouseCertiId());
        batchDeletedResource(one.getIndoorId());
        batchDeletedResource(one.getHouseTypeId());
        //修改图片
        batchAddResource(tbHouseInfoVo.getResource(),one.getResourceId());
        batchAddResource(tbHouseInfoVo.getHouseCerti(),one.getHouseCertiId());
        batchAddResource(tbHouseInfoVo.getHouseTypeImg(),one.getIndoorId());
        batchAddResource(tbHouseInfoVo.getIndoor(),one.getHouseTypeId());
        //修改房源特色
        QueryWrapper<TbHouseFeature> tbHouseFeatureQueryWrapper = new QueryWrapper<>();
        tbHouseFeatureQueryWrapper.lambda().eq(TbHouseFeature::getHouseId,tbHouseInfoVo.getId());
        TbHouseFeature tbHouseFeature = tbHouseFeatureService.getOne(tbHouseFeatureQueryWrapper);
        if (null==tbHouseFeature){
            return ResultVo.FAILED(ResponseState.NOT_EXIST);
        }
        tbHouseFeature.setProprietorMentality(tbHouseInfoVo.getProprietorMentality());
        tbHouseFeature.setCoreSellPoint(tbHouseInfoVo.getCoreSellPoint());
        tbHouseFeature.setServerIntro(tbHouseInfoVo.getServerIntro());
        tbHouseFeatureService.updateById(tbHouseFeature);
        //修改
        int update = tbHouseInfoMapper.updateById(one);
        return update==1?ResultVo.SUCCESS():ResultVo.FAILED(ResponseState.UPDATE_ERROR);
    }

    private void batchDeletedResource(String resourceId) {
        QueryWrapper<TbResource> tbResourceQueryWrapper = new QueryWrapper<>();
        tbResourceQueryWrapper.lambda().eq(TbResource::getResourceId,resourceId);
        tbResourceService.remove(tbResourceQueryWrapper);
    }

    @Override
    public ResultVo deleted(TbHouseInfoVo tbHouseInfoVo) {
        TbHouseInfo tbHouseInfo = new TbHouseInfo();
        //将vo对象转为po对象
        BeanUtils.copyProperties(tbHouseInfoVo,tbHouseInfo);
        QueryWrapper<TbHouseInfo> tbHouseInfoQueryWrapper = new QueryWrapper<>();
        tbHouseInfoQueryWrapper.lambda().eq(TbHouseInfo::getId,tbHouseInfo.getId());
        //获取一个房源
        TbHouseInfo one = tbHouseInfoMapper.selectOne(tbHouseInfoQueryWrapper);
        if (null == one){
            return ResultVo.FAILED(ResponseState.NOT_EXIST);
        }
        //删除
        int deleted = tbHouseInfoMapper.deleteById(tbHouseInfo);
        if (one.getBrokerId()!=null){
            //经纪人的房屋-1
             brokerFeignService.subtractBrokerHouse(new BrokerHouseNumVo(one.getTypeId(),one.getBrokerId()));
        }
        return deleted==1?ResultVo.SUCCESS():ResultVo.FAILED(ResponseState.DELETE_ERROR);
    }


    @Override
    public ResultVo houseList(TbHouseInfoVo tbHouseInfoVo) {
        //分页
        Page<TbHouseInfoVo> tbHouseInfoPage = null;
        if (tbHouseInfoVo.getPageNum()!=null && tbHouseInfoVo.getPageSize()!=null) {
            tbHouseInfoPage = new Page<>(tbHouseInfoVo.getPageNum(), tbHouseInfoVo.getPageSize());
        }
        Page<TbHouseInfoVo> page = tbHouseInfoMapper.houseList(tbHouseInfoPage,tbHouseInfoVo);
        List<TbHouseInfoVo> records = page.getRecords();
        for (int i = 0; i < records.size(); i++) {
            records.get(i).setKey(i+1);
        }
        page.setRecords(records);
        return ResultVo.SUCCESS(page);
    }


    @Override
    public ResultVo assign(AssignVo assignVo) {
        ResultVo resultVo = null;
        if (StringUtils.isNotEmpty(assignVo.getBrokerName())){
            //获取指派的经纪人姓名
            resultVo = brokerFeignService.getByName(assignVo.getBrokerName());
        }
        Integer tbHouseBrokerId = (Integer) resultVo.getData();

        if(null==tbHouseBrokerId){
            //指派的经纪人不存在
            return ResultVo.FAILED(ResponseState.BROKER_NOT_EXIST);
        }
        //修改房源数据
        TbHouseInfo tbHouseInfo = new TbHouseInfo();
        tbHouseInfo.setId(assignVo.getId());
        tbHouseInfo.setBrokerId(Integer.valueOf(tbHouseBrokerId));
        tbHouseInfo.setStatus(1);
        int update = tbHouseInfoMapper.updateById(tbHouseInfo);
        //经纪人房源数量+1
        int append =  brokerFeignService.appendBrokerHouse(new BrokerHouseNumVo(assignVo.getTypeId(),tbHouseBrokerId));
        return update==1&&append==1?ResultVo.SUCCESS():ResultVo.FAILED(ResponseState.UPDATE_ERROR);
    }

    @Override
    public ResultVo houseContent(IdVo idVo) {
        //获取信息
        TbHouseInfoVo tbHouseInfoVO = tbHouseInfoMapper.getById(idVo.getId());
        //查地区,查标签
        String tag = tbHouseInfoVO.getTag();
        String[] split = tag.split(",");
        AreaVo areaVo = tbDictionaryClient.getAreas(tbHouseInfoVO);
        ArrayList<String> strings = new ArrayList<>();
        for (String s : split) {
            strings.add(s);
        }
        TagsVo tagsVo = new TagsVo(strings);
        List<String> tags = tbDictionaryClient.getTags(tagsVo);
        tbHouseInfoVO.setProvince(areaVo.getProvince());
        tbHouseInfoVO.setCity(areaVo.getCity());
        tbHouseInfoVO.setCounty(areaVo.getCounty());
        tbHouseInfoVO.setTags(tags);
        //查房子图片
        ArrayList<String> resourceList = getResourceList(tbHouseInfoVO.getResourceId());
        ArrayList<String> houseCertiList = getResourceList(tbHouseInfoVO.getHouseCertiId());
        ArrayList<String> houseTypeList = getResourceList(tbHouseInfoVO.getHouseTypeId());
        ArrayList<String> indoor = getResourceList(tbHouseInfoVO.getIndoorId());
        //包装
        tbHouseInfoVO.setResource(resourceList);
        tbHouseInfoVO.setHouseCerti(houseCertiList);
        tbHouseInfoVO.setHouseTypeImg(houseTypeList);
        tbHouseInfoVO.setIndoor(indoor);
        QueryWrapper<TbHouseFeature> tbHouseFeatureQueryWrapper = new QueryWrapper<>();
        tbHouseFeatureQueryWrapper.lambda().eq(TbHouseFeature::getHouseId,tbHouseInfoVO.getId());
        TbHouseFeature tbHouseFeature = tbHouseFeatureService.getOne(tbHouseFeatureQueryWrapper);
        tbHouseInfoVO.setProprietorMentality(tbHouseFeature.getProprietorMentality());
        tbHouseInfoVO.setCoreSellPoint(tbHouseFeature.getCoreSellPoint());
        tbHouseInfoVO.setServerIntro(tbHouseFeature.getServerIntro());
        return ResultVo.SUCCESS(tbHouseInfoVO);
    }

    private ArrayList<String> getResourceList(String resourceId) {
        QueryWrapper<TbResource> tbResourceQueryWrapper = new QueryWrapper<>();
        tbResourceQueryWrapper.lambda().eq(TbResource::getResourceId,resourceId);
        List<TbResource> list = tbResourceService.list(tbResourceQueryWrapper);
        ArrayList<String> resourceList = new ArrayList<>();
        for (TbResource tbResource : list) {
            resourceList.add(tbResource.getUrl());
        }
        return resourceList;
    }

    @Override
    public ResultVo brokerList(TbHouseInfoVo tbHouseInfoVo) {
        TbHouseInfo tbHouseInfo = tbHouseInfoMapper.selectById(tbHouseInfoVo.getId());
        Set data = brokerFeignService.getByCountyId(tbHouseInfo.getCountyId());
        return ResultVo.SUCCESS(data);
    }


    @Override
    public ResultVo login(LoginVo loginVo) {
        //手机号验证码登录
        if (StringUtils.isEmpty(loginVo.getPhone())){
            return ResultVo.FAILED(ResponseState.MOBILE_NOT_NULL);
        }
        QueryWrapper<TbAdmin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbAdmin::getMobile,loginVo.getPhone());
        TbAdmin admin = tbAdminService.getOne(queryWrapper);
        if (admin==null){
            return ResultVo.FAILED(ResponseState.MOBILE_ERROR);
        }
        String jwsKey="SearchHouse";
        //判断验证码
        String redisCode = (String) redisTemplate.opsForValue().get("code" + loginVo.getPhone());
        if (null==redisCode){
            //验证码失效
            return ResultVo.FAILED(ResponseState.CODE_ERROR_EXPIRED);
        }
        if (!redisCode.equals(loginVo.getCode())){
            //登录失败
            return ResultVo.FAILED(ResponseState.CODE_ERROR);
        }
        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, jwsKey)
                .claim("id",admin.getId())
        .compact();
        redisTemplate.opsForValue().set(token,token,5, TimeUnit.MINUTES);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("token",token);
        //脱敏
        admin.setId(null);
        admin.setMobile(null);
        hashMap.put("admin", JSON.toJSONString(admin));
        return ResultVo.SUCCESS(hashMap);
    }

    @Override
    public Boolean getAdminByPhone(String phone) {
        QueryWrapper<TbAdmin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TbAdmin::getMobile,phone);
        TbAdmin admin = tbAdminService.getOne(queryWrapper);
        if (admin==null){
            return false;
        }
        return true;
    }


}




